package ClientLibrary.Network;

import ClientLibrary.Logger;
import CommonLibrary.Commnads.*;
import CommonLibrary.NoCloseInputStream;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class NetLayer {

	private Logger log;
	private int port;
	private String adress;
	private CommandsSerializer serializer;
	private NoCloseInputStream input;
	private OutputStream output;
	private Socket socket;
	
	public NetLayer(Logger log, String address, int port) throws Exception {
		this.log = log;
		this.adress = address;
		this.port = port;
        Class classes[] = new Class[18];
        classes[0] = AuthorizeResponse.class;
        classes[1] = RegisterResponse.class;
        classes[2] = MoveRequest.class;
        classes[3] = MoveResponse.class;
        classes[4] = AuthorizeRequest.class;
        classes[5] = RegisterRequest.class;
        classes[6] = WinOrLoseResponse.class;
        classes[7] = StartGameResponse.class;
        classes[8] = ListRequest.class;
        classes[9] = ListResponse.class;
        classes[10] = CreateGameRequest.class;
        classes[11] = CreateGameResponse.class;
        classes[12] = JoinGameRequest.class;
        classes[13] = JoinGameResponse.class;
        classes[14] = EnemyMoveRequest.class;
        classes[15] = EnemyMoveResponse.class;
        classes[16] = MoveRequest.class;
        classes[17] = MoveResponse.class;
		serializer = new CommandsSerializer(classes);
	}

	public void connect() throws IOException {
		//log.addMessage("Connecting to... " + address + ":" + port);
		socket = new Socket(adress, port);
        /*
		if (socket.isConnected())
        {
		    log.addMessage("Connected!");
		}
        else
        {
		    throw new IOException("Can't connect.");
		}
        */
		input = new NoCloseInputStream(socket.getInputStream());
		output = socket.getOutputStream();
	}
	
	public void sendCommand(Command command) throws Exception {
        this.connect();
		serializer.writeCommandToStream(output, command);
		socket.shutdownOutput();
		log.addMessage("Command sent: " + command.getClass().toString());
	}
	
	public Command startReceivingCommand() throws Exception {
        Command command = (Command)serializer.getCommandFromStream(input);
        log.addMessage("Command received: "  + command.getClass().toString());
        return command;
	}
}
